
package it.benchmark;

import it.enrollement.Extract;
import it.enrollement.Setup;
import it.enrollement.System_Param;
import it.ibgka.IB_BD_BLS;
import it.ibgka.IB_BD_DSA;
import it.ibgka.IB_BD_ZSS;
import it.ibgka.IB_GKA_BLS;
import it.ibgka.IB_GKA_DSA;
import it.ibgka.IB_GKA_ZSS;
import it.ibka.IB_FG;
import it.ibs.IB_BLS;
import it.ibs.IB_BLS_MNT;
import it.ibs.IB_DSA;
import it.ibs.IB_ZSS;
import it.user.Param_ibdsa;
import it.user.User;
import java.util.Random;
import java.util.UUID;
import jpair.api.Pairing;
import jpair.pairing.Point;
import jpair.pairing.Predefined;
import jpair.pairing.PairingFactory;
/**
 * The benchmark class is used to measures scheme and protocols performances in term of computation time (ms).  
 * @author Francesco Rossi
 * @version 0.1
 * 
 */
public class Benchmark {

    Setup setup;
    Extract extract;
    System_Param param;
    static int n ;
    static User[] m ;

    public static void setN(int n) {
        Benchmark.n = n;
    }

    public Benchmark(int n,Pairing pairing) {


        param = new System_Param();
        setup = new Setup(pairing);
        extract = new Extract();
        this.n = n;
        m = new User[n];
 
    }

    public void Test_Setup() {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1=0L,med2 = 0L;
        System.out.println("Test Setup: ");
        System.out.println("");


        ntest = 1;
        for (j = 0; j < ntest; j++) {

           
            startTime = System.nanoTime();
            setup.Init(param);
            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

       /*  
            
            if (j == 0) {
                med1 = 0L;
            }
*/


        }

        System.out.println("");
        System.out.println("Setup Execution Time");
        System.out.println("Setup =" + ((med1 / (ntest)) / 1000000) + "ms");
        System.out.println("");


    }

    public void Test_Extract() {
        int j, ntest;
        int i;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L;
        System.out.println("Test Extract: ");
        System.out.println("");


        ntest = 1;
        for (j = 0; j < ntest; j++) {

            startTime = System.nanoTime();

            for (i = 0; i < n; i++) {


                m[i] = new User();


                m[i].setID(UUID.randomUUID().toString());


                extract.Init(param, m[i], m[i].getID());


            }
              endTime = System.nanoTime() - startTime;
             med1 = med1 + endTime; 
      
      /*      
            if (j == 0) {
                med1 = 0L;
            }
*/

        }


        System.out.println("");
        System.out.println("Extract Execution Time for " + n + " Users");
        System.out.println("Extract =" + ((med1 / (ntest)) / 1000000) + "ms");
        System.out.println("");


    }

    /**
     * 
     * @param m The users involed
     * @param n The number of users
     */
    
    
    public void Test_IB_FG(User[] m, int n) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_FG: ");
        System.out.println("");

        IB_FG ibka = new IB_FG(m, n, param);
             ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;

            startTime = System.nanoTime();
            ibka.Round1();
            endTime = System.nanoTime() - startTime;
            med3 = med3 + endTime;

            startTime = System.nanoTime();
            ibka.KeyDerivation();
            endTime = System.nanoTime() - startTime;
            med4 = med4 + endTime;


         

        }
        System.out.println("");
        System.out.println("IB_FG Execution Time for 2 Users");
          System.out.println("Round1 =" + (((med3 / ntest) / 1000000) / n) + "ms");
         System.out.println("KeyDerivation =" + (((med4 / ntest) / 1000000) / n) + "ms");
         System.out.println("Total =" + ((((med3 / ntest) / 1000000) / n) + (((med4 / ntest) / 1000000) / n)) + "ms");
        System.out.println("");

    }

    /**
     * 
     * 
     * @param A The user that run sign and verify procedure 
     */
    
    
    public void Test_IB_BLS(User A) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_BLS: ");
        System.out.println("");

        IB_BLS ib_bls = new IB_BLS(param);
              ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            //random message
            String m = UUID.randomUUID().toString();

            Point sigma = ib_bls.sign(m, A.getKbls());

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            boolean res = ib_bls.vrf(m, A.getID(), sigma);

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;


        
        }
        System.out.println("");
        System.out.println("IB_BLS Execution Time");
        System.out.println("Signature =" + ((med1 / ntest) / 1000000) + "ms");
        System.out.println("Verification =" + ((med2 / ntest) / 1000000) + "ms");
        System.out.println("");

    }
public void Test_IB_BLS_MNT(User A) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_BLS: ");
        System.out.println("");

        IB_BLS_MNT ib_bls = new IB_BLS_MNT(param);
              ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            //random message
            String m = UUID.randomUUID().toString();

            Point sigma = ib_bls.sign(m, A.getKbls());

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            boolean res = ib_bls.vrf(m, A.getID(), sigma);

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;


        
        }
        System.out.println("");
        System.out.println("IB_BLS Execution Time");
        System.out.println("Signature =" + ((med1 / ntest) / 1000000) + "ms");
        System.out.println("Verification =" + ((med2 / ntest) / 1000000) + "ms");
        System.out.println("");

    }

    
     public void Test_IB_DSA(User A) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_DSA: ");
        System.out.println("");

        IB_DSA ib_dsa = new IB_DSA(param);
              ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            //random message
            String m = UUID.randomUUID().toString();

            Param_ibdsa sigma = ib_dsa.sign(m, A.getKdsa());

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            boolean res = ib_dsa.vrf(m, A.getID(), sigma, A.getTid());

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;


        
        }
        System.out.println("");
        System.out.println("IB_DSA Execution Time");
        System.out.println("Signature =" + ((med1 / ntest) / 1000000) + "ms");
        System.out.println("Verification =" + ((med2 / ntest) / 1000000) + "ms");
        System.out.println("");

    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /**
     * 
     * 
     * @param A The user that run sign and verify procedure 
     */
   public void Test_IB_ZSS(User A) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_ZSS: ");
        System.out.println("");

        IB_ZSS tibs = new IB_ZSS(param);
              ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            //random message
            String m = UUID.randomUUID().toString();

            Point sigma = tibs.sign(m, A.getKzss());

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            boolean res = tibs.vrf(m, A.getID(), sigma);

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;


       

        }
        System.out.println("");
        System.out.println("IB_ZSS Execution Time");
        System.out.println("Signature =" + ((med1 / ntest) / 1000000) + "ms");
        System.out.println("Verification =" + ((med2 / ntest) / 1000000) + "ms");
        System.out.println("");

    }

     /**
     * 
     * @param m The users involed
     * @param n The number of users
     */
    public void Test_IB_GKA_ZSS(User[] m, int n) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_GKA_ZSS: ");
        System.out.println("");

        IB_GKA_ZSS ibgka_zss = new IB_GKA_ZSS(m, n, param);
     
        ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            ibgka_zss.Round1();

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            ibgka_zss.Round2();

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;

            startTime = System.nanoTime();

            ibgka_zss.KeyDerivation();

            endTime = System.nanoTime() - startTime;
            med3 = med3 + endTime;


         
        }
        System.out.println("");
        if (ibgka_zss.getFlag()) {
            System.out.println("");
            System.out.println("IB_GKA_ZSS Execution Time");
            System.out.println("Round1 =" + (((med1 / ntest) / 1000000) / n) + "ms");
            System.out.println("Round2 =" + (((med2 / ntest) / 1000000) / n) + "ms");
            System.out.println("KeyDerivation =" + (((med3 / ntest) / 1000000) / n) + "ms");
            Long total = (((med1 / ntest) / 1000000) / n) + (((med2 / ntest) / 1000000) / n) + (((med3 / ntest) / 1000000) / n);

            System.out.println("Total =" + total + "ms");
            System.out.println("");
        } else {
            System.out.println("Signature Verification = False");
        }

    }

      /**
     * 
     * @param m The users involed
     * @param n The number of users
     */
    public void Test_IB_GKA_BLS(User[] m, int n) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_GKA_BLS: ");
        System.out.println("");

        IB_GKA_BLS ibgka_bls = new IB_GKA_BLS(m, n, param);
      
            ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            ibgka_bls.Round1();

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            ibgka_bls.Round2();

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;

            startTime = System.nanoTime();

            ibgka_bls.KeyDerivation();

            endTime = System.nanoTime() - startTime;
            med3 = med3 + endTime;


        
        }
        System.out.println("");
        if (ibgka_bls.getFlag()) {
            System.out.println("");
            System.out.println("IB_GKA_BLS Execution Time");
            System.out.println("Round1 =" + (((med1 / ntest) / 1000000) / n) + "ms");
            System.out.println("Round2 =" + (((med2 / ntest) / 1000000) / n) + "ms");
            System.out.println("KeyDerivation =" + (((med3 / ntest) / 1000000) / n) + "ms");
            Long total = (((med1 / ntest) / 1000000) / n) + (((med2 / ntest) / 1000000) / n) + (((med3 / ntest) / 1000000) / n);

            System.out.println("Total =" + total + "ms");
            System.out.println("");
        } else {
            System.out.println("Signature Verification = False");
        }

    }
  /**
     * 
     * @param m The users involed
     * @param n The number of users
     */
    public void Test_IB_BD_ZSS(User[] m, int n) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_BD_ZSS: ");
        System.out.println("");

        IB_BD_ZSS ibgka_zss = new IB_BD_ZSS(m, n, param);
        // ibga tibgka=new ibga(m,n,param);
          ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            ibgka_zss.Round1();

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            ibgka_zss.Round2();

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;

            startTime = System.nanoTime();

            ibgka_zss.KeyDerivation();

            endTime = System.nanoTime() - startTime;
            med3 = med3 + endTime;


       
        }
        System.out.println("");
        if (ibgka_zss.getFlag()) {
            System.out.println("");
            System.out.println("IB_BD_ZSS Execution Time");
            System.out.println("Round1 =" + (((med1 / ntest) / 1000000) / n) + "ms");
            System.out.println("Round2 =" + (((med2 / ntest) / 1000000) / n) + "ms");
            System.out.println("KeyDerivation =" + (((med3 / ntest) / 1000000) / n) + "ms");
            Long total = (((med1 / ntest) / 1000000) / n) + (((med2 / ntest) / 1000000) / n) + (((med3 / ntest) / 1000000) / n);

            System.out.println("Total =" + total + "ms");
            System.out.println("");
        } else {
            System.out.println("Signature Verification = False");
        }

    }
  /**
     * 
     * @param m The users involed
     * @param n The number of users
     */
    public void Test_IB_BD_BLS(User[] m, int n) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_BD_BLS");
        System.out.println("");

        IB_BD_BLS ibgka_bls = new IB_BD_BLS(m, n, param);
        // ibga tibgka=new ibga(m,n,param);
            ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            ibgka_bls.Round1();

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            ibgka_bls.Round2();

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;

            startTime = System.nanoTime();

            ibgka_bls.KeyDerivation();

            endTime = System.nanoTime() - startTime;
            med3 = med3 + endTime;


        }
        System.out.println("");
        if (ibgka_bls.getFlag()) {
            System.out.println("");
            System.out.println("IB_BD_BLS Execution Time");
            System.out.println("Round1 =" + (((med1 / ntest) / 1000000) / n) + "ms");
            System.out.println("Round2 =" + (((med2 / ntest) / 1000000) / n) + "ms");
            System.out.println("KeyDerivation =" + (((med3 / ntest) / 1000000) / n) + "ms");
            Long total = (((med1 / ntest) / 1000000) / n) + (((med2 / ntest) / 1000000) / n) + (((med3 / ntest) / 1000000) / n);

            System.out.println("Total =" + total + "ms");
            System.out.println("");
        } else {
            System.out.println("Signature Verification = False");
        }

    } 
    
     /**
     * 
     * @param m The users involed
     * @param n The number of users
     */
    public void Test_IB_BD_DSA(User[] m, int n) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_BD_DSA");
        System.out.println("");

        IB_BD_DSA ibgka_dsa = new IB_BD_DSA(m, n, param);
        // ibga tibgka=new ibga(m,n,param);
            ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            ibgka_dsa.Round1();

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            ibgka_dsa.Round2();

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;

            startTime = System.nanoTime();

            ibgka_dsa.KeyDerivation();

            endTime = System.nanoTime() - startTime;
            med3 = med3 + endTime;


        }
        System.out.println("");
        if (ibgka_dsa.getFlag()) {
            System.out.println("");
            System.out.println("IB_BD_DSA Execution Time");
            System.out.println("Round1 =" + (((med1 / ntest) / 1000000) / n) + "ms");
            System.out.println("Round2 =" + (((med2 / ntest) / 1000000) / n) + "ms");
            System.out.println("KeyDerivation =" + (((med3 / ntest) / 1000000) / n) + "ms");
            Long total = (((med1 / ntest) / 1000000) / n) + (((med2 / ntest) / 1000000) / n) + (((med3 / ntest) / 1000000) / n);

            System.out.println("Total =" + total + "ms");
            System.out.println("");
        } else {
            System.out.println("Signature Verification = False");
        }

    }
     /**
     * 
     * @param m The users involed
     * @param n The number of users
     */
    public void Test_IB_GKA_DSA(User[] m, int n) {
        int j, ntest;
        Long startTime = 0L, endTime = 0L;
        Long med1 = 0L, med2 = 0L, med3 = 0L, med4 = 0L, med5 = 0L;
        System.out.println("Test IB_GKA_DSA: ");
        System.out.println("");

        IB_GKA_DSA ibgka_dsa = new IB_GKA_DSA(m, n, param);
      
            ntest = 1;
        for (j = 0; j < ntest; j++) {

                med1 = 0L;
                med2 = 0L;
                med3 = 0L;
            startTime = System.nanoTime();

            ibgka_dsa.Round1();

            endTime = System.nanoTime() - startTime;
            med1 = med1 + endTime;

            startTime = System.nanoTime();

            ibgka_dsa.Round2();

            endTime = System.nanoTime() - startTime;
            med2 = med2 + endTime;

            startTime = System.nanoTime();

            ibgka_dsa.KeyDerivation();

            endTime = System.nanoTime() - startTime;
            med3 = med3 + endTime;


        
        }
        System.out.println("");
        if (ibgka_dsa.getFlag()) {
            System.out.println("");
            System.out.println("IB_GKA_DSA Execution Time");
            System.out.println("Round1 =" + (((med1 / ntest) / 1000000) / n) + "ms");
            System.out.println("Round2 =" + (((med2 / ntest) / 1000000) / n) + "ms");
            System.out.println("KeyDerivation =" + (((med3 / ntest) / 1000000) / n) + "ms");
            Long total = (((med1 / ntest) / 1000000) / n) + (((med2 / ntest) / 1000000) / n) + (((med3 / ntest) / 1000000) / n);

            System.out.println("Total =" + total + "ms");
            System.out.println("");
        } else {
            System.out.println("Signature Verification = False");
        }

    }
    public static void main(String[] args) {
      
        
  /*! \mainpage My Personal Index Page
 *
 * \section intro_sec Abstract
 *
 * we present JEDI (Java Environment for Distributed Identities), a 
Java framework for identity-based, peer-to-peer secure communications. 
This kind of communications is relevant for some emerging distributed environments 
such as wireless sensor networks and, more generally, whenever a set of peers needs
to autonomously perform secure interactions without the burden given by creation 
and management of public-key certificates. 
JEDI is an ongoing project which in its first release implements an enrollment
service, two signature schemes and five protocols for authenticated key-agreement.
A first set of experimental results with JEDI shows that its performances are 
comparable to implementations in lower level languages, and that it implements some
very fast and scalable authenticated group key agreement protocols. 
These features makes JEDI very suitable for distributed applications requiring
secure group communications at low cost. 
 *
 * @author Francesco Rossi
 * @version 0.1
 * 
 *  
 * 
 */   
 // The number of users n
       int n=1; 
    //    Benchmark b = new Benchmark(n,Predefined.ssTate160());
    //   Pairing ep =PairingFactory.ssTate(160, 512, new Random());
       int[] groupsize ={160,192,224,256,384,521};
        int[] fieldsize ={512,1536,2048,3072,7680,15360};
      //    
        int i=0;
    //    for (i=0; i< groupsize.length;i++){
            Benchmark b = new Benchmark(n,Predefined.bn256());
        //    Pairing ep =PairingFactory.ssTate(groupsize[i], fieldsize[i], new Random());
           // Benchmark b = new Benchmark(n,ep);
       b.Test_Setup();
       
       b.Test_Extract();
    //   b.Test_IB_FG(m, 2);
      b.Test_IB_BLS_MNT(m[0]);
         b.Test_IB_BLS(m[0]);
      //  }
      b.Test_IB_ZSS(m[0]);
      b.Test_IB_DSA(m[0]);
   //  b.Test_IB_BD_BLS(m, n);
     //  b.Test_IB_BD_ZSS(m, n);
      
     //  b.Test_IB_GKA_BLS(m, n);
    //   b.Test_IB_GKA_ZSS(m, n);
       
     //   b.Test_IB_BD_DSA(m, n);
     //   b.Test_IB_GKA_DSA(m, n);

    }
}
